package org.adream.account.util;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpClientUtil {

	private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

	public static CookieStore cookieStore = new BasicCookieStore();

	public static CloseableHttpClient httpClient = HttpClients.custom()
			.setConnectionManager(new PoolingHttpClientConnectionManager()).setDefaultCookieStore(cookieStore)
			.setConnectionManagerShared(true).build();

	/**
	 * list参数方式POST提交
	 * @param url
	 * @param list
	 * @return
	 */
	public static String httpPost(String url, List<BasicNameValuePair> list) {
		// 配置超时时间
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(1000).setConnectionRequestTimeout(1000)
				.setSocketTimeout(1000).setRedirectsEnabled(true).build();

		HttpPost httpPost = new HttpPost(url);
		// 设置超时时间
		httpPost.setConfig(requestConfig);

		String result = "";
		int StatusCode = 404;
		try {
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
			// 设置post求情参数
			httpPost.setEntity(entity);
			HttpResponse httpResponse = httpClient.execute(httpPost);

			if (httpResponse != null) {
				StatusCode = httpResponse.getStatusLine().getStatusCode();
				if (httpResponse.getStatusLine().getStatusCode() == 200) {
					result = EntityUtils.toString(httpResponse.getEntity());
					logger.info("post/" + StatusCode + ":" + result);
					return result;
				} else {
					result = "Error Response: " + httpResponse.getStatusLine().toString();
					logger.info("post/" + StatusCode + ":" + result);
					result = null;
				}
			} else {
				result = null;
			}

		} catch (Exception e) {
			logger.error(e.getMessage());
		} finally {
			if (httpClient != null) {
				try {
					httpClient.close();
				} catch (IOException e) {
					logger.error(e.getMessage());
				}
			}
		}
		return result;
	}

	/**
	 * map参数方式POST提交
	 * @param url
	 * @param paramsMap
	 * @return
	 */
	public static String httpMapPost(String url, Map<String, Object> paramsMap) {
		CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
		// 配置连接超时时间
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000)
				.setSocketTimeout(5000).setRedirectsEnabled(true).build();
		HttpPost httpPost = new HttpPost(url);
		// 设置超时时间
		httpPost.setConfig(requestConfig);

		// 装配post请求参数
		List<NameValuePair> list = new ArrayList<NameValuePair>();
		for (String key : paramsMap.keySet()) {
			list.add(new BasicNameValuePair(key, String.valueOf(paramsMap.get(key))));
		}
		try {
			// 将参数进行编码为合适的格式,如将键值对编码为param1=value1&param2=value2
			UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list, "utf-8");
			httpPost.setEntity(urlEncodedFormEntity);

			// 执行 post请求
			CloseableHttpResponse closeableHttpResponse = closeableHttpClient.execute(httpPost);
			String strRequest = "";
			if (null != closeableHttpResponse && !"".equals(closeableHttpResponse.toString())) {
				if (closeableHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
					HttpEntity httpEntity = closeableHttpResponse.getEntity();
					strRequest = EntityUtils.toString(httpEntity);
				} else {
					strRequest = "Error Response" + closeableHttpResponse.getStatusLine().getStatusCode();
				}
			}
			return strRequest;
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			return "协议异常";
		} catch (ParseException e) {
			e.printStackTrace();
			return "解析异常";
		} catch (IOException e) {
			e.printStackTrace();
			return "传输异常";
		} finally {
			try {
				if (closeableHttpClient != null) {
					closeableHttpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * jsonstring参数方式POST提交
	 * @param url
	 * @param json
	 * @return
	 */
	public static String httpJsonStringPost(String url, String json) {
		CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
		// 配置连接超时时间
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000)
				.setSocketTimeout(5000).setRedirectsEnabled(true).build();
		HttpPost httpPost = new HttpPost(url);
		// 设置超时时间
		httpPost.setConfig(requestConfig);
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8"); // 添加请求头
		httpPost.setEntity(new StringEntity(json, "utf-8"));
		try {
			// 执行 post请求
			CloseableHttpResponse closeableHttpResponse = closeableHttpClient.execute(httpPost);
			String strRequest = "";
			if (null != closeableHttpResponse && !"".equals(closeableHttpResponse.toString())) {
				if (closeableHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
					HttpEntity httpEntity = closeableHttpResponse.getEntity();
					strRequest = EntityUtils.toString(httpEntity);
				} else {
					strRequest = "Error Response" + closeableHttpResponse.getStatusLine().getStatusCode();
				}
			}
			return strRequest;
		} catch (ClientProtocolException e) {
			logger.warn("jsonobject参数方式POST提交失败:" + e.getMessage());
			return "协议异常";
		} catch (ParseException e) {
			logger.warn("jsonobject参数方式POST提交失败:" + e.getMessage());
			return "解析异常";
		} catch (IOException e) {
			logger.warn("jsonobject参数方式POST提交失败:" + e.getMessage());
			return "传输异常";
		} finally {
			try {
				if (closeableHttpClient != null) {
					closeableHttpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * object参数方式POST提交
	 * @param url
	 * @param obj
	 * @return
	 */
	public static String httpObjectPost(String url, Object obj) {
		CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
		// 配置连接超时时间
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000)
				.setSocketTimeout(5000).setRedirectsEnabled(true).build();
		HttpPost httpPost = new HttpPost(url);
		// 设置超时时间
		httpPost.setConfig(requestConfig);
		// 装配post请求参数
		List<NameValuePair> list = new ArrayList<NameValuePair>();
		// 反射获取对象属性与值
		Field[] declaredFields = obj.getClass().getDeclaredFields();
		for (Field field : declaredFields) {
			field.setAccessible(true);
			try {
				if(field.get(obj) != null) {					
					list.add(new BasicNameValuePair(field.getName(), (String) field.get(obj)));
				}
			} catch (IllegalArgumentException e) {
				logger.warn("反射获取数据失败:" + e.getMessage());
				return e.getMessage();
			} catch (IllegalAccessException e) {
				logger.warn("反射获取数据失败:" + e.getMessage());
				return e.getMessage();
			}
		}
		try {
			// 将参数进行编码为合适的格式,如将键值对编码为param1=value1&param2=value2
			UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list, "utf-8");
			httpPost.setEntity(urlEncodedFormEntity);

			// 执行 post请求
			CloseableHttpResponse closeableHttpResponse = closeableHttpClient.execute(httpPost);
			String strRequest = "";
			if (null != closeableHttpResponse && !"".equals(closeableHttpResponse.toString())) {
				if (closeableHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
					HttpEntity httpEntity = closeableHttpResponse.getEntity();
					strRequest = EntityUtils.toString(httpEntity);
				} else {
					logger.warn("Error Response" + closeableHttpResponse.getStatusLine().getStatusCode());
					strRequest = null;
				}
			}
			return strRequest;
		} catch (ClientProtocolException e) {
			logger.warn("协议异常");
			return null;
		} catch (ParseException e) {
			logger.warn("解析异常");
			return null;
		} catch (IOException e) {
			logger.warn("传输异常");
			return null;
		} finally {
			try {
				if (closeableHttpClient != null) {
					closeableHttpClient.close();
				}
			} catch (IOException e) {
				logger.warn(e.getMessage());
			}
		}
	}

	/**
	 * GET获取
	 * @param url
	 * @return
	 */
	public static String HttpGet(String url) {
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000) // 设置连接超时时间
				.setConnectionRequestTimeout(5000) // 设置请求超时时间
				.setSocketTimeout(5000).setRedirectsEnabled(true)// 默认允许自动重定向
				.build();
		HttpGet httpGet2 = new HttpGet(url);
		httpGet2.setConfig(requestConfig);
		String srtResult = null;
		int StatusCode = 404;
		try {
			CloseableHttpResponse httpResponse = httpClient.execute(httpGet2);
			StatusCode = httpResponse.getStatusLine().getStatusCode();
			if (httpResponse.getStatusLine().getStatusCode() == 200) {
				srtResult = EntityUtils.toString(httpResponse.getEntity());// 获得返回的结果
				logger.info("get/" + StatusCode + ":" + srtResult);
				return srtResult;
			} else {
				srtResult = EntityUtils.toString(httpResponse.getEntity());// 获得返回的结果
				logger.info("get/" + StatusCode + ":" + srtResult);
				return null;
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (httpClient != null) {
				try {
					httpClient.close();
				} catch (IOException e) {
					logger.error(e.getMessage());
				}
			}
		}
		return null;
	}

	public static void setCookieStore(List<BasicClientCookie> cookielist) {
		for (BasicClientCookie cookie : cookielist) {
			HttpClientUtil.cookieStore.addCookie(cookie);
		}
	}

	public static void createCookie(List<BasicClientCookie> cookielist) {
		for (BasicClientCookie cookie : cookielist) {
			HttpClientUtil.cookieStore.addCookie(cookie);
		}
	}
}